package com.k.base.jdk.thread.thread;

import com.k.base.jdk.thread.ThreadFactoryBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author kivil
 */
public class ThreadTest {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread()+":start");
//        ThreadTemplate threadTemplate = new ThreadTemplate();
//        CompletableFuture<String> future = threadTemplate.executeTask(()->{
//            String name = "hello";
//            System.out.println(Thread.currentThread()+":"+name);
//            return name;
//        });
//        try {
//            future.get();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        } catch (ExecutionException e) {
//            e.printStackTrace();
//        }
//        threadTemplate.shutdown();
        test();
        System.out.println(Thread.currentThread()+":end");
    }
    private static void executeTask(){
        /**
         * Thread[download_th_thread_0,5,main]:1
         * Thread[download_th_thread_1,5,main]:2
         * Thread[download_th_thread_2,5,main]:3
         * Thread[download_th_thread_3,5,main]:4
         */
//        ExecutorService executorService = new ThreadPoolExecutor(
//                // 核心线程
//                5,
//                // 最大线程
//                5,
//                // 10(maximumPoolSize) -5(corePoolSize) = 5(新建的线程) 这 5个新建的线程 ,空闲时间(keepAliveTime),退出。
//                5, TimeUnit.SECONDS,
//                new LinkedBlockingQueue<>(32),
//                new ThreadFactoryBuilder().setNameFormat("download").setDaemon(false).build(),
//                new ThreadPoolExecutor.AbortPolicy()
//        );
        /**
         * Thread[pool-1-thread-1,5,main]:1
         * Thread[pool-1-thread-2,5,main]:2
         * Thread[pool-1-thread-3,5,main]:3
         * Thread[pool-1-thread-4,5,main]:4
         */
        ThreadPoolExecutor executorService = new ThreadPoolExecutor(
                4,
                5,
                3000,
                TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(5));
        try {
            test1(executorService);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            executorService.shutdown();
        }
    }
    private static void test1(ExecutorService executorService) throws ExecutionException, InterruptedException {
        System.out.println(Thread.currentThread()+":start");
        CompletableFuture<String> result = CompletableFuture
                .supplyAsync(() -> {
                    String hello = "hello ";
                            System.out.println(Thread.currentThread() + ":" +hello);
                            return hello;
                        }
                        , executorService)
                .thenApplyAsync((v) -> {
                    String res = v + "world";
                    System.out.println(Thread.currentThread() + ":" +res);
                    return res;
                })
//                .join()
                ;
        System.out.println(Thread.currentThread() + ":" + result.get());
        System.out.println(Thread.currentThread()+":end");
    }
    private static void test2(ExecutorService executorService){
        System.out.println("test2():"+Thread.currentThread());
        List<Integer> ids = new ArrayList<>();
        ids.add(1);
        ids.add(2);
        ids.add(3);
        ids.add(4);
        ids.add(5);

        AtomicInteger resultOrder = new AtomicInteger(0);
        ConcurrentHashMap<Integer,Integer> map = new ConcurrentHashMap();
        CompletableFuture<Integer>[] completableFutures = ids.stream().map(id -> {
            return CompletableFuture.supplyAsync(() -> {
                try {
                    if(id.equals(3)){
                        TimeUnit.SECONDS.sleep(1);

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(id.equals(4)){
                    System.out.println(2/0);
                }
                System.out.println(Thread.currentThread()+"supplyAsync():"+id);
                map.put(resultOrder.getAndIncrement(),id);
                return id;
            },executorService).whenComplete((a,e)->{
                if(e!=null){
                    System.out.println(Thread.currentThread()+"异常");
                }
                System.out.println(Thread.currentThread()+"whenComplete():"+a);
            });
        }).toArray(CompletableFuture[]::new);

//        System.out.println("等待所有任务执行完,有异常会中断主线程");
//        CompletableFuture.allOf(completableFutures).join();
//        System.out.println("所有任务执行完毕");
//
//        // 按照执行顺序返回结果
//        System.out.println("按照执行顺序返回结果");
//        for (CompletableFuture<Integer> completableFuture : completableFutures) {
//            try {
//                System.out.print(completableFuture.get()+",");
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//        System.out.println();
//        System.out.println("按照线程执行返回结果速度返回结果");
//        for(Map.Entry<Integer,Integer> entry: map.entrySet()){
//            System.out.print(entry.getValue()+",");
//        }
        System.out.println("test2() end:"+Thread.currentThread());
    }

    private static void test(){
        System.out.println(Thread.currentThread()+":start");
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread()+":"+"mytask");

            }
        });
        thread.setDaemon(false);
//        thread.setName("dowload");
        thread.start();
        System.out.println(Thread.currentThread()+":end");
    }
}
